package com.lefevre.cms.service.payment.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lefevre.cms.bean.QueryResult;
import com.lefevre.cms.bean.payment.OnlinePaymentInterface;
import com.lefevre.cms.bean.payment.PaymentLog;
import com.lefevre.cms.bean.payment.PaymentVerificationLog;
import com.lefevre.cms.mapper.OnlinePaymentInterfaceMapper;
import com.lefevre.cms.mapper.PaymentLogMapper;
import com.lefevre.cms.mapper.PaymentVerificationLogMapper;
import com.lefevre.cms.service.besa.DaoSupport;
import com.lefevre.cms.service.payment.PaymentService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 支付管理实现类
 *
 * @author Lefevre
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class PaymentServiceImpl extends DaoSupport<OnlinePaymentInterface> implements PaymentService {
    private static final Logger logger = LoggerFactory.getLogger(PaymentServiceImpl.class);

    @Resource
    private PaymentLogMapper paymentLogMapper;
    @Resource
    private OnlinePaymentInterfaceMapper onlinePaymentInterfaceMapper;
    @Resource
    private PaymentVerificationLogMapper paymentVerificationLogMapper;

    /**
     * 根据Id查询在线支付接口
     *
     * @param onlinePaymentInterfaceId 在线支付接口Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public OnlinePaymentInterface findOnlinePaymentInterfaceById(Integer onlinePaymentInterfaceId) {
        return onlinePaymentInterfaceMapper.selectById(onlinePaymentInterfaceId);
    }

    /**
     * 查询所有有效的在线支付接口
     *
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<OnlinePaymentInterface> findAllEffectiveOnlinePaymentInterface() {
        return onlinePaymentInterfaceMapper.selectList(new LambdaQueryWrapper<OnlinePaymentInterface>()
                .eq(OnlinePaymentInterface::isEnable, true)
                .orderByDesc(OnlinePaymentInterface::getSort));
    }

    /**
     * 查询所有有效的在线支付接口
     *
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    @Cacheable(value = "paymentServiceBean_cache", key = "'findAllEffectiveOnlinePaymentInterface_default'")
    public List<OnlinePaymentInterface> findAllEffectiveOnlinePaymentInterface_cache() {
        return this.findAllEffectiveOnlinePaymentInterface();
    }

    /**
     * 查询所有在线支付接口
     *
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public List<OnlinePaymentInterface> findAllOnlinePaymentInterface() {
        return onlinePaymentInterfaceMapper.selectList(null);
    }

    /**
     * 保存在线支付接口
     *
     * @param onlinePaymentInterface 在线支付接口
     */
    @CacheEvict(value = "paymentServiceBean_cache", allEntries = true)
    public void saveOnlinePaymentInterface(OnlinePaymentInterface onlinePaymentInterface) {
        onlinePaymentInterfaceMapper.insert(onlinePaymentInterface);
    }

    /**
     * 修改在线支付接口
     *
     * @param onlinePaymentInterface 在线支付接口
     */
    @CacheEvict(value = "paymentServiceBean_cache", allEntries = true)
    public void updateOnlinePaymentInterface(OnlinePaymentInterface onlinePaymentInterface) {
        this.update(onlinePaymentInterface);
    }


    /**
     * 删除在线支付接口
     *
     * @param onlinePaymentInterfaceId 在线支付接口Id
     */
    @CacheEvict(value = "paymentServiceBean_cache", allEntries = true)
    public Integer deleteOnlinePaymentInterface(Integer onlinePaymentInterfaceId) {
        return onlinePaymentInterfaceMapper.deleteById(onlinePaymentInterfaceId);
    }

    /** --------------------------------- 支付校验日志 -------------------------------------- **/


    /**
     * 根据Id查询支付校验日志
     *
     * @param paymentVerificationLogId 支付流水号
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public PaymentVerificationLog findPaymentVerificationLogById(String paymentVerificationLogId) {
        return paymentVerificationLogMapper.selectById(paymentVerificationLogId);
    }

    /**
     * 保存支付校验日志
     *
     * @param paymentVerificationLog 支付校验日志
     */
    public void savePaymentVerificationLog(PaymentVerificationLog paymentVerificationLog) {
        paymentVerificationLogMapper.insert(paymentVerificationLog);
    }

    /**
     * 根据Id删除支付校验日志
     *
     * @param paymentVerificationLogId 支付流水号
     */
    public Integer deletePaymentVerificationLogById(String paymentVerificationLogId) {
        return paymentVerificationLogMapper.deleteById(paymentVerificationLogId);
    }


    /** --------------------------------- 支付日志 -------------------------------------- **/
    /**
     * 保存支付日志
     * 先由paymentManage.createPaymentLogObject();方法生成对象再保存
     *
     * @param paymentLog 支付日志
     */
    public void savePaymentLog(Object paymentLog) {
        paymentLogMapper.insert((PaymentLog) paymentLog);
    }

    /**
     * 根据支付流水号查询支付日志
     *
     * @param paymentRunningNumber 支付流水号
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public PaymentLog findPaymentLogByPaymentRunningNumber(String paymentRunningNumber) {
        return paymentLogMapper.selectOne(new LambdaQueryWrapper<PaymentLog>()
                .eq(PaymentLog::getPaymentRunningNumber, paymentRunningNumber));
    }

    /**
     * 支付日志分页
     *
     * @param userId     用户Id
     * @param userName   用户名称
     * @param firstIndex 索引开始,即从哪条记录开始
     * @param maxResult  获取多少条数据
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public QueryResult<PaymentLog> findPaymentLogPage(Long userId, String userName, int firstIndex, int maxResult) {
        QueryResult<PaymentLog> qr = new QueryResult<>();

        LambdaQueryWrapper<PaymentLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PaymentLog::getUserName, userName);
        wrapper.orderByDesc(PaymentLog::getTimes);
        Page<PaymentLog> paymentLogPage = paymentLogMapper.selectPage(new Page<>(firstIndex, maxResult), wrapper);

        qr.setResultlist(paymentLogPage.getRecords());
        qr.setTotalrecord(paymentLogPage.getTotal());

        return qr;
    }
}
